package com.solrtest.service.impl;

import com.solrtest.doman.Product;
import com.solrtest.doman.Shop;
import com.solrtest.service.TemplateProductService;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.SolrInputDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.FilterQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.SimpleStringCriteria;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TemplateProductServiceImpl implements TemplateProductService {

    private final String coreName = "wlx";
    private final String coreNameShop = "jts";
    private final SolrTemplate solrTemplate;
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public TemplateProductServiceImpl(SolrTemplate solrTemplate, JdbcTemplate jdbcTemplate) {
        this.solrTemplate = solrTemplate;
        this.jdbcTemplate = jdbcTemplate;
    }


    @Override
    public void add(Product product) {
        SolrInputDocument sid = new SolrInputDocument();
        sid.addField("id", product.getId());
        sid.addField("productName", product.getProductName());
        sid.addField("productPrice", product.getProductPrice());
        sid.addField("productSpec", product.getProductSpec());
        sid.addField("createTime", product.getCreateTime());
        sid.addField("isDel", product.getIsDel());

        UpdateResponse response = solrTemplate.saveDocument(coreName, sid);
        solrTemplate.commit(coreName);
        System.out.println("over:" + response);
    }

    @Override
    public void edit(Product product) {
        UpdateResponse updateResponse = solrTemplate.saveBean(coreName, product);
        System.out.println(updateResponse);
    }

    //删除  https://spring.hhui.top/spring-blog/2020/01/14/200114-SpringBoot%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8BSolr%E4%B9%8B%E6%96%87%E6%A1%A3%E5%88%A0%E9%99%A4/
    @Override
    public void del(String id) {
        UpdateResponse updateResponse = solrTemplate.deleteByIds(coreName, id);
        System.out.println(updateResponse);
    }

    @Override
    public List<Product> queryByIds(List<String> ids) {
        Collection<Product> collection = solrTemplate.getByIds(coreName, ids, Product.class);
        return new ArrayList<>(collection);
    }

    @Override
    public Page<Product> queryAll() {
        return solrTemplate.query(coreName, new SimpleQuery("*:*"), Product.class);
    }

    @Override
    public List<Product> query(Product product) {

        SimpleQuery query = new SimpleQuery();

        // 多个查询条件
        Criteria criteria = Criteria.where("productName").contains(product.getProductName())
                .and("id").between(1, 10);
        query.addCriteria(criteria);

        // fq 过滤
        FilterQuery filterQuery = FilterQuery.filter(Criteria.where("productName").contains(product.getProductName()));
        query.addFilterQuery(filterQuery);

        // fl 返回指定的字段
        query.addProjectionOnFields("id", "productName", "productPrice");

        // 排序
        query.addSort(Sort.by("id").descending());

        return solrTemplate.query(coreName, query, Product.class).getContent();
    }


    @Override
    public UpdateResponse addShopInfo() {
        //固定
//        List<Shop> list = new ArrayList<>();
//        list.add(new Shop(4, "北京-朝外店", "北京市朝阳区朝外sohoD座5110", "116.460557", "39.932558"));
//        list.add(new Shop(6, "北京-人大店", "北京市海淀区北三环西路47号院乙10-6号", "116.320896", "39.97292"));
//        list.add(new Shop(11, "北京-顺义店", "北京市顺义区西辛南区55号楼南侧西辛南区市场106号", "116.649471", "40.14375"));
//        list.add(new Shop(12, "北京-通州店", "北京市通州区梨园镇孙王场村委会北100米永盛超市底商", "116.666536", "39.895731"));
//        list.add(new Shop(13, "北京-霍营店", "北京市昌平区农业部干部管理学院东门", "116.374155", "40.087722"));
//        list.add(new Shop(15, "北京-大兴店", "北京市大兴区黄村镇清源路甲1号2幢1层5号", "116.351174", "39.751916"));
//        list.add(new Shop(16, "北京-方庄店", "北京市朝阳区成寿寺路134号院中海城紫鑫阁", "116.454459", "39.855097"));
//        list.add(new Shop(17, "北京-六里桥店", "北京市丰台区六里桥西三环中路太平27号楼底商", "116.318273", "39.897132"));
//        list.add(new Shop(18, "北京-洋桥店", "北京市角门东里12号楼西侧底商117号维尔纳斯", "116.391781", "39.856717"));
//        list.add(new Shop(19, "北京-安贞店", "北京市黄寺大街15号佰隆大厦4层423", "116.397372", "39.980888"));
//        list.add(new Shop(23, "北京-昌平南口店", "昌平区南口镇兴隆街麦利宝手感烘焙", "116.134199", "40.244248"));
//        list.add(new Shop(34, "北京-石景山店", "石景山区古盛路36号院（中海金鑫阁）3号楼3019号", "116.189029", "39.929496"));
//        list.add(new Shop(37, "北京-上地店", "安宁庄西路9号院25号楼1层112（imoma大厦底商，佳汇儿园对面）", "116.321404", "40.057441"));
//        list.add(new Shop(42, "北京-亦庄店", "天华北街5号院一层西侧103维尔纳斯", "116.504375", "39.817262"));
//        list.add(new Shop(48, "北京-石佛营店", "北京市朝阳区卜蜂莲花超市（石佛营店）内", "116.508188", "39.937419"));
//        list.add(new Shop(53, "北京-昌平店", "昌平区鼓楼南大街38~4", "116.239485", "40.222828"));
//        list.add(new Shop(96, "北京-沙河店", "沙河镇松兰堡村西海林自控院内一楼148室", "116.293338", "40.161073"));
//        list.add(new Shop(108, "北京-房山店", "北京市房山区阜盛东街57号院4号楼1层105", "116.198006", "39.746316"));
//        list.add(new Shop(122, "北京-来广营店", "朝阳区来广营 铁建广场 D座1层105室", "116.44598", "40.053336"));
//        list.add(new Shop(159, "北京-顺义2店", "北京市顺义区顺仁路66号院2号楼B112底商", "116.672922", "40.091715"));
//        UpdateResponse updateResponse = solrTemplate.saveBeans("jts", list);
//        solrTemplate.commit("jts");


        //数据库批量
        NamedParameterJdbcTemplate nameJdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
        RowMapper<Shop> rm = BeanPropertyRowMapper.newInstance(Shop.class);
        String sql = "select id,shop_name,address,lat,lng from erp_shop ";
        List<Shop> list = nameJdbc.query(sql, new HashMap<>(), rm);
        UpdateResponse updateResponse = solrTemplate.saveBeans("jts", list);
        solrTemplate.commit("jts");
        return updateResponse;
    }

    //这个不能返回距离字段不知道该怎么写，感觉还是solrj更好用一此，怎么这spring这样一封装感觉反人类呢
    @Override
    public List<Shop> getByGps(String gps) {

        SimpleQuery query = new SimpleQuery();
        // fl 返回指定的字段
        query.addProjectionOnField("*");


        //查询条件
        StringBuilder buf = new StringBuilder();
        buf.append("{!geofilt pt=39.939549858674226,116.82007871201711");//查询坐标
        buf.append(" sfield=position d=50.0}"); //门店GPS地址  和 查询距离以内 公里


        query.addCriteria(new SimpleStringCriteria(buf.toString()));

        //排序
        query.addSort(Sort.by("score").ascending());
        return solrTemplate.query(coreNameShop, query, Shop.class).getContent();
    }

    @Override
    public Map<String, Object> readTime() {
        Map<String, Object> map = new HashMap<>();
        long s, e, max = 1000;
        int solrNum = 0, dbNum = 0;
        int qTime = 0;

        s = System.currentTimeMillis();
        for (int i = 0; i < max; i++) {
            SimpleQuery query = new SimpleQuery("*:*");
            query.setOffset(0L);
            query.setRows(500);
            List<Shop> list = solrTemplate.query("jts", query, Shop.class).getContent();
            solrNum += list.size();
        }
        e = System.currentTimeMillis();
        map.put("solr", "耗时:" + ((e - s) / 1000) + "秒,共" + solrNum + "条数据!");

        s = System.currentTimeMillis();
        for (int i = 0; i < max; i++) {
            NamedParameterJdbcTemplate nameJdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
            RowMapper<Shop> rm = BeanPropertyRowMapper.newInstance(Shop.class);
            String sql = "select id,shop_name,address,lat,lng from erp_shop ";
            List<Shop> list = nameJdbc.query(sql, new HashMap<>(), rm);
            dbNum += list.size();
        }
        e = System.currentTimeMillis();
        map.put("db", "耗时:" + ((e - s) / 1000) + "秒,共" + dbNum + "条数据!");
        return map;
    }
}
